<?php
namespace App\Actions;

use App\Models\AdminUser;
use App\Models\DdbUser;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\TemplateProcessor;
use Intervention\Image\Facades\Image;
use QL\QueryList;

class DdbUserAction extends BaseAction {

    public $admin_user;

    public function __construct(AdminUser $adminUser = null)
    {
        $this->admin_user = $adminUser;
    }

    public function dealWord($uploadfile)
    {
        $table = 'ddb_users';
        $admin_user = $this->admin_user;
        $uploadfile = file_local_path($uploadfile);
        $phpwriter = IOFactory::load($uploadfile);
        $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpwriter, "HTML");
        $filename = $this->admin_user && $this->admin_user->ddb_dwmc ? $this->admin_user->ddb_dwmc . '_' . time() . ".html" : time().'.html';
        $basedir = 'ddb_users';
        $dir = storage_path('app/public/' . $basedir);
        @mkdir($dir, 0777, true);
        $file = $dir . '/' . $filename;
        $xmlWriter ->save($file);
        if (!file_exists($file)) {
            $this->error('文件上传失败');
        }

        $html = file_get_contents($file);
        $tableInit = QueryList::html($html)->find('table');
        // DOM解析表头
        // $tableHeader = $table->find('tr:eq(0)')->find('td')->texts();
        // DOM解析表的每行内容
        $tableRowsForTexts = $tableInit->find('tr:gte(0)')->map(function($row){
            return $row->find('td')->texts()->all();
        })->toArray();
        $tableRowsForHtmls = $tableInit->find('tr:gt(6)')->map(function($row){
            return $row->find('td')->htmls()->all();
        })->toArray();
        if (count($tableRowsForTexts) != 13) {
            $this->error('请以模板为基础进行修改，整个表格共有13行');
        }
        if (!isset($tableRowsForTexts[0]) || count($tableRowsForTexts[0]) != 7) {
            $this->error('请以模板为基础进行修改，姓名所在的表格一行，共有7列');
        }
        $insert_data['name'] = trim_space($tableRowsForTexts[0][1]);
        $insert_data['sex'] = trim_space($tableRowsForTexts[0][3]);
        $insert_data['csrq'] = trim_space($tableRowsForTexts[0][5]);
        $zp_area = trim_space($tableRowsForTexts[0][6]);
        if ($zp_area != '${照片替换区域请不要修改这里的文字}') {
            $this->error('文档中照片区域请参考模板，不得修改照片区域的文字信息');
        }

        if (!$insert_data['name']) {
            $this->error('请填写姓名');
        }

        # 民族一行
        if (!isset($tableRowsForTexts[1]) || count($tableRowsForTexts[1]) != 6) {
            $this->error('请以模板为基础进行修改，民族所在的表格一行，共有6列');
        }
        $insert_data['mz'] = trim_space($tableRowsForTexts[1][1]);
        $insert_data['jg'] = trim_space($tableRowsForTexts[1][3]);
        $insert_data['jrsj'] = trim_space($tableRowsForTexts[1][5]);

        # 参加工作时间
        if (!isset($tableRowsForTexts[2]) || count($tableRowsForTexts[2]) != 6) {
            $this->error('请以模板为基础进行修改，参加工作时间所在的表格一行，共有6列');
        }
        $insert_data['cjgzsj'] = trim_space($tableRowsForTexts[2][1]);
        $insert_data['zyjszw'] = trim_space($tableRowsForTexts[2][3]);
        $insert_data['jkzk'] = trim_space($tableRowsForTexts[2][5]);

        # 人员类别
        if (!isset($tableRowsForTexts[3]) || count($tableRowsForTexts[3]) != 4) {
            $this->error('请以模板为基础进行修改，人员类别所在的表格一行，共有6列');
        }
        $insert_data['rylb'] = trim_space($tableRowsForTexts[3][1]);
        $insert_data['lxfs'] = trim_space($tableRowsForTexts[3][3]);

        # 学历 全日制
        if (!isset($tableRowsForTexts[4]) || count($tableRowsForTexts[4]) != 5) {
            $this->error('请以模板为基础进行修改，学历信息区域无错误');
        }
        $insert_data['qrzjy'] = json_encode(explode("\r\n", $tableRowsForTexts[4][2]));
        $insert_data['qrzjy_yx'] = json_encode(explode("\r\n", $tableRowsForTexts[4][4]));
        # 学历 在职
        if (!isset($tableRowsForTexts[5]) || count($tableRowsForTexts[5]) != 4) {
            $this->error('请以模板为基础进行修改，学历信息区域无错误');
        }
        $insert_data['zzjy'] = json_encode(explode("\r\n", $tableRowsForTexts[5][1]));
        $insert_data['zzjy_yx'] = json_encode(explode("\r\n", $tableRowsForTexts[5][3]));

        # 现任职务
        if (!isset($tableRowsForTexts[6]) || count($tableRowsForTexts[6]) != 2) {
            $this->error('请以模板为基础进行修改，现任职务所在的一行有错误');
        }
        $insert_data['xrzw'] = trim_space($tableRowsForTexts[6][1]);

        $seconds = ['jl', 'zzlssc', 'jcqk', 'zybx', 'yj', 'bz'];
        foreach($seconds as $index => $key) {
            if (!isset($tableRowsForHtmls[$index]) || count($tableRowsForHtmls[$index]) != 2) {
                $this->error('请以模板为基础进行修改');
            }
            $insert_data[$key] = $tableRowsForHtmls[$index][1];
        }
        # 删除生成的html
        if ($file && file_exists($file)) {
            @unlink($file);
        }

        unset($tableRowsForHtmls);
        unset($tableRowsForTexts);

        return $insert_data;
    }

    /**
     * 新增导入
     */
    public function import($inputs)
    {
        $is_edit = false;
        $table = 'ddb_users';
        $admin_user = $this->admin_user;
        if (!$admin_user->ddb_dwdm) {
            $this->error('您没有设置所在单位，无法上传');
        }
        try {
            $insert_data = $this->dealWord($inputs['file']);
        } catch (\Throwable $th) {
            Log::info("文件内容读取失败".$th->getMessage());
            $this->error($th->getMessage());
            // $this->error('文件内容读取失败，只允许上传office word docx格式的文件');
        }
        $insert_data['filepath'] = $inputs['file'];
        # 新增
        if (!isset($inputs['zp']) || !$inputs['zp'] || !file_exists(file_local_path($inputs['zp']))) {
            $this->error('请上传照片');
        }
        $avatar = $inputs['zp'];
        $insert_data['zp'] = $this->dealZp($insert_data['name'], $inputs['zp']);
        $new_filepath = $this->reNewWordWithAvatar($insert_data['filepath'], $insert_data['zp'], $admin_user->ddb_dwmc, $insert_data['name']);
        if (is_array($new_filepath) && isset($new_filepath['status']) && $new_filepath['status'] == 'error') {
            $this->error($new_filepath['message']);
        }

        $old_relation_row = null;
        $insert_data['new_filepath'] = $new_filepath;
        if (DB::table($table)->where('name', $insert_data['name'])->where('dwdm', $admin_user->ddb_dwdm)->exists()) {
            $insert_data['updated_by_gid'] = $admin_user->gid;
            $insert_data['updated_at'] = date("Y-m-d H:i:s");
            $relation_row = DB::table($table)->where('name', $insert_data['name'])->where('dwdm', $admin_user->ddb_dwdm)->first();
            $old_relation_row = $relation_row;
            DB::table($table)->where('id', $relation_row->id)->update($insert_data);
            $id = $relation_row->id;
        } else {
            $insert_data['created_by_gid'] = $admin_user->gid;
            $insert_data['updated_by_gid'] = $admin_user->gid;
            $insert_data['dwdm'] = $admin_user->ddb_dwdm;
            $insert_data['dwmc'] = $admin_user->ddb_dwmc;
            $id = DB::table($table)->insertGetId($insert_data);
        }
        unset($insert_data);
    }

    /**
     * 修改，重新上传
     */
    public function reupload($inputs, DdbUser $ddbUser)
    {
        $table = 'ddb_users';
        $admin_user = $this->admin_user;
        // if (!$admin_user->ddb_dwdm) {
        //     $this->error('您没有设置所在单位，无法上传');
        // }
        $old_relation_row = DB::table($table)->where('id', $ddbUser->id)->first();

        $upload_type = $inputs['upload_type'];
        if ($upload_type == 'zp') {
            $old_avatar = $ddbUser->zp; # 旧照片，方便后面删除旧照片

            # 如果是修改照片
            if (!isset($inputs['avatar']) || !$inputs['avatar'] || !file_exists(file_local_path($inputs['avatar']))) {
                $this->error('请上传照片');
            }
            $avatar = $inputs['avatar'];
            $zp = $this->dealZp($ddbUser->name, $avatar);
            # 带有照片的新文档
            $new_filepath = $this->reNewWordWithAvatar($ddbUser->filepath, $zp, $ddbUser->dwmc, $ddbUser->name);
            if (is_array($new_filepath) && isset($new_filepath['status']) && $new_filepath['status'] == 'error') {
                $this->error($new_filepath['message']);
            }
            $ddbUser->update(['zp' => $zp, 'new_filepath' => $new_filepath]);
            # 删除旧的生成的文件
            if ($old_relation_row) {
                $this->deleteOldNewWords($old_relation_row);
            }
            if ($old_avatar && file_exists(file_local_path($old_avatar))) {
                @unlink(file_local_path($old_avatar));
            }
            if ($avatar && file_exists(file_local_path($avatar))) {
                @unlink(file_local_path($avatar));
            }
        } else {
            # 修改的文件
            if (!isset($inputs['file']) || !$inputs['file'] || !file_exists(file_local_path($inputs['file']))) {
                $this->error('请上传文件');
            }
            try {
                $insert_data = $this->dealWord($inputs['file']);
            } catch (\Throwable $th) {
                $this->error($th->getMessage());
                // $this->error('文件内容读取失败，只允许上传office word docx格式的文件');
            }
            $insert_data['filepath'] = $inputs['file'];
            if (DdbUser::query()->where('name', $insert_data['name'])->where('dwdm', $ddbUser->dwdm)->where('id', '<>',$ddbUser->id)->exists()) {
                $this->error("姓名{$insert_data['name']}已经存在");
            }
            # 带有照片的新文档
            $new_filepath = $this->reNewWordWithAvatar($insert_data['filepath'], $ddbUser->zp, $ddbUser->dwmc, $insert_data['name']);
            if (is_array($new_filepath) && isset($new_filepath['status']) && $new_filepath['status'] == 'error') {
                $this->error($new_filepath['message']);
            }
            $insert_data['new_filepath'] = $new_filepath;
            $insert_data['updated_by_gid'] = $admin_user->gid;
            $insert_data['updated_at'] = date("Y-m-d H:i:s");
            DB::table($table)->where('id', $ddbUser->id)->update($insert_data);
            unset($insert_data);
            # 删除旧的生成的文件
            if ($old_relation_row) {
                $this->deleteOldFiles($old_relation_row);
            }
        }
    }

    /**
     * 重新生成新的带有头像word
     */
    public function reNewWordWithAvatar($filepath, $zp, $dwmc, $name)
    {
        try {
            $origin_file = file_local_path($filepath);
            if (!file_exists($origin_file)) {
                Log::info($dwmc . $name . '的文件不存在');
                return ['status' => 'error', 'message' => "未找到上传的源文件信息"];
            }
            if (!file_exists(file_local_path($zp))) {
                Log::info($dwmc . $name . '的照片('.$zp.')文件不存在');
                return ['status' => 'error', 'message' => '未找到照片信息'];
            }
            $zp = file_host_path($zp);

            //实例化 phpword 类
            $phpWordProcessor = new TemplateProcessor($origin_file); //加载模板文件
            $phpWordProcessor->setImageValue('照片替换区域请不要修改这里的文字', ['path'=>$zp,'width'=>110, 'height' => 170, 'ratio' =>false]);
            
            $basedir = 'ddb_users/'.date("Y").'/newwords';
            if (!is_dir(file_local_path($basedir))) {
                @mkdir(file_local_path($basedir), 0777, true);
            }
            # 带有照片的新的word名称
            $newfilename = $dwmc."_{$name}_".date("ymdHis").randomkeys(4).".docx";
            $newfilepath = $basedir . "/" . $newfilename;
            $savePath = storage_path('app/public/' . $newfilepath);
            $phpWordProcessor->saveAs($savePath);
            return $newfilepath;
        } catch (\Throwable $th) {
            Log::info($dwmc . $name . '的新文档生成失败；' . $th->getMessage());
            return ['status' => 'error', 'message' => '新文档生成失败'];
        }
    }

    public function deleteOldFiles($old_relation_row)
    {
        try {
            if (!$old_relation_row) {
                return;
            }
            if ($old_relation_row->filepath && file_exists(file_local_path($old_relation_row->filepath))) {
                @unlink(file_local_path($old_relation_row->filepath));
            }
            if ($old_relation_row->new_filepath && file_exists(file_local_path($old_relation_row->new_filepath))) {
                @unlink(file_local_path($old_relation_row->new_filepath));
            }
        } catch (\Throwable $th) {
            //throw $th;
        }
    }

    public function deleteOldNewWords($old_relation_row) {
        try {
            if (!$old_relation_row) {
                return;
            }
            if ($old_relation_row->new_filepath && file_exists(file_local_path($old_relation_row->new_filepath))) {
                @unlink(file_local_path($old_relation_row->new_filepath));
            }
        } catch (\Throwable $th) {
            //throw $th;
        }
    }

    public function dealZp($name, $old_zp) {
        try {
            $extension = pathinfo($old_zp, PATHINFO_EXTENSION);
            $newzpfile = $name . randomkeys(5) . '.' . $extension;

            $newpath_basedir = 'ddb_users/'.date("Y").'/avatars';

            $newpath = $newpath_basedir .DIRECTORY_SEPARATOR. $newzpfile;
            // $to_path = 'ddb_users/avatars/'. $newzpfile;
            // if (file_exists(file_local_path($to_path))) {
            //     #  如果有已经存在一个同名的文件
            // }

            try {
                $image = Image::make(file_local_path($old_zp));
                if ($image->getWidth() > 500) {
                    Image::make(file_local_path($old_zp))->resize(500, null, function($con){
                        $con->aspectRatio();//按比例裁剪
                        $con->upsize();
                    })->save(file_local_path($newpath));
                } else {
                    Storage::disk('public')->copy($old_zp, $newpath);
                }
            } catch (\Throwable $th) {
                # 如果有压缩出错了，则保持原来的文件
                Storage::disk('public')->copy($old_zp, $newpath);
            }
            // @unlink(file_local_path($old_zp));
            return $newpath;
        } catch (\Throwable $th) {
            Log::info("{$name}上传照片失败" . $th->getMessage());
        }
    }
}